﻿namespace ImageProcessing
{
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Runtime.InteropServices;
    using System.Text;

    public static class PHFastCpp
    {
        const string dllLocation = "PHFast.dll";

        #region Resize
        [DllImport(dllLocation, EntryPoint = "PHResizeNearestNeighbor", CallingConvention = CallingConvention.Cdecl)]
        public static extern void PHResizeNearestNeighbor(int addressOriginal, int addressNew, int originalWidth, int newWidth, int newHeight, int originalExtraBytes, int newExtraBytes, double widthRatio, double heightRatio);

        [DllImport(dllLocation, EntryPoint = "PHResizeBillinear", CallingConvention = CallingConvention.Cdecl)]
        public static extern void PHResizeBillinear(int addressOriginal, int addressNew, int originalWidth, int originalHeight, int newWidth, int newHeight, int originalExtraBytes, int newExtraBytes, double heightRatio, double widthRatio);

        [DllImport(dllLocation, EntryPoint = "PHResizeBiCubicBSpline", CallingConvention = CallingConvention.Cdecl)]
        public static extern void PHResizeBiCubicBSpline(int addressOriginal, int addressNew, int originalWidth, int originalHeight, int newWidth, int newHeight, int originalExtraBytes, int newExtraBytes, double heightRatio, double widthRatio);

        [DllImport(dllLocation, EntryPoint = "PHResizeBiCubicBell", CallingConvention = CallingConvention.Cdecl)]
        public static extern void PHResizeBiCubicBell(int addressOriginal, int addressNew, int originalWidth, int originalHeight, int newWidth, int newHeight, int originalExtraBytes, int newExtraBytes, double heightRatio, double widthRatio);

        [DllImport(dllLocation, EntryPoint = "PHResizeBiCubicTriangular", CallingConvention = CallingConvention.Cdecl)]
        public static extern void PHResizeBiCubicTriangular(int addressOriginal, int addressNew, int originalWidth, int originalHeight, int newWidth, int newHeight, int originalExtraBytes, int newExtraBytes, double heightRatio, double widthRatio);

        [DllImport(dllLocation, EntryPoint = "PHResizeBiCubicCatMullRom", CallingConvention = CallingConvention.Cdecl)]
        public static extern void PHResizeBiCubicCatMullRom(int addressOriginal, int addressNew, int originalWidth, int originalHeight, int newWidth, int newHeight, int originalExtraBytes, int newExtraBytes, double heightRatio, double widthRatio);
        #endregion

        #region Filters
        [DllImport(dllLocation, EntryPoint = "PHAdaptiveMedian", CallingConvention = CallingConvention.Cdecl)]
        public static extern void PHAdaptiveMedian(int address, int newAddress, int width, int height, int oldExtraBytes, int newExtraBytes, int k);

        [DllImport(dllLocation, EntryPoint = "PHMin2D", CallingConvention = CallingConvention.Cdecl)]
        public static extern void PHMin2D(int address, int newAddress, int width, int height, int oldExtraBytes, int newExtraBytes, int k);

        [DllImport(dllLocation, EntryPoint = "PHMin1D", CallingConvention = CallingConvention.Cdecl)]
        public static extern void PHMin1D(int address, int newAddress, int width, int height, int oldExtraBytes, int newExtraBytes, int k);

        [DllImport(dllLocation, EntryPoint = "PHMax2D", CallingConvention = CallingConvention.Cdecl)]
        public static extern void PHMax2D(int address, int newAddress, int width, int height, int oldExtraBytes, int newExtraBytes, int k);

        [DllImport(dllLocation, EntryPoint = "PHMax1D", CallingConvention = CallingConvention.Cdecl)]
        public static extern void PHMax1D(int address, int newAddress, int width, int height, int oldExtraBytes, int newExtraBytes, int k);

        [DllImport(dllLocation, EntryPoint = "PHMidPoint", CallingConvention = CallingConvention.Cdecl)]
        public static extern void PHMidPoint(int address, int newAddress, int width, int height, int oldExtraBytes, int newExtraBytes, int k);

        [DllImport(dllLocation, EntryPoint = "PHMedian", CallingConvention = CallingConvention.Cdecl)]
        public static extern void PHMedian(int address, int newAddress, int width, int height, int oldExtraBytes, int newExtraBytes, int k);

        [DllImport(dllLocation, EntryPoint = "PHGeometric", CallingConvention = CallingConvention.Cdecl)]
        public static extern void PHGeometric(int address, int newAddress, int width, int height, int oldExtraBytes, int newExtraBytes, int k);

        [DllImport(dllLocation, EntryPoint = "PHArithmetic", CallingConvention = CallingConvention.Cdecl)]
        public static extern void PHArithmetic(int address, int newAddress, int width, int height, int oldExtraBytes, int newExtraBytes, int k);

        [DllImport(dllLocation, EntryPoint = "PHMean1DFilter", CallingConvention = CallingConvention.Cdecl)]
        public static extern void PHMean1DFilter(int addressOriginal, int addressNew, int width, int height, int oldExtraBytes, int newExtraBytes, int k);

        [DllImport(dllLocation, EntryPoint = "PHGaussian1DFilter", CallingConvention = CallingConvention.Cdecl)]
        public static extern void PHGaussian1DFilter(int addressOriginal, int addressNew, int width, int height, int oldExtraBytes, int newExtraBytes, double sigma);
        #endregion

        #region Equalization
        [DllImport(dllLocation, EntryPoint = "HistogramMatching", CallingConvention = CallingConvention.Cdecl)]
        public static extern void HistogramMatching(int addressOriginal1, int addressOriginal2, int addressNew, int original1Width, int original1Height, int original2Width, int original2Height, int original1ExtraBytes, int original2ExtraBytes, int newExtraBytes);

        [DllImport(dllLocation, EntryPoint = "HistogramEqualization", CallingConvention = CallingConvention.Cdecl)]
        public static extern void HistogramEqualization(int addressOriginal, int addressNew, int originalWidth, int originalHeight, int originalExtraBytes);

        [DllImport(dllLocation, EntryPoint = "GetEqlization", CallingConvention = CallingConvention.Cdecl)]
        public static extern void GetEqlization(int addressOriginal, int originalWidth, int originalHeight, int originalExtraBytes, double[] red, double[] green, double[] blue);
        #endregion

        [DllImport(dllLocation, EntryPoint = "PHLinearConvolution", CallingConvention = CallingConvention.Cdecl)]
        public static extern void PHLinearConvolution(int addressOriginal, int addressNew, int width, int height, int extraBytes, double[,] mask, int k, int postProcessing);

        #region General operations
        [DllImport(dllLocation, EntryPoint = "PHAdd", CallingConvention = CallingConvention.Cdecl)]
        public static extern void PHAdd(int addressOriginal1, int addressOriginal2, int addressNew, int width, int height, int extraBytes, float fraction);

        [DllImport(dllLocation, EntryPoint = "PHSub", CallingConvention = CallingConvention.Cdecl)]
        public static extern void PHSub(int addressOriginal1, int addressOriginal2, int addressNew, int width, int height, int extraBytes);

        [DllImport(dllLocation, EntryPoint = "PHOr", CallingConvention = CallingConvention.Cdecl)]
        public static extern void PHOr(int addressOriginal1, int addressOriginal2, int addressNew, int width, int height, int extraBytes);

        [DllImport(dllLocation, EntryPoint = "PHAnd", CallingConvention = CallingConvention.Cdecl)]
        public static extern void PHAnd(int addressOriginal1, int addressOriginal2, int addressNew, int width, int height, int extraBytes);

        [DllImport(dllLocation, EntryPoint = "PHNot", CallingConvention = CallingConvention.Cdecl)]
        public static extern void PHNot(int addressOriginal, int addressNew, int width, int height, int extraBytes);

        [DllImport(dllLocation, EntryPoint = "PHGreyscale", CallingConvention = CallingConvention.Cdecl)]
        public static extern void PHGreyscale(int addressOriginal, int addressNew, int width, int height, int extraBytes);
        #endregion

        #region Add Noise
        [DllImport(dllLocation, EntryPoint = "PHAddSalt_PepperNoise", CallingConvention = CallingConvention.Cdecl)]
        public static extern void PHAddSalt_PepperNoise(int addressOriginal, int width, int height, int extraBytes, double saltProbability, double pepperProbability, int noisePercentage);

        [DllImport(dllLocation, EntryPoint = "PHAddUniformNoise", CallingConvention = CallingConvention.Cdecl)]
        public static extern void PHAddUniformNoise(int addressOriginal, int width, int height, int extraBytes, int a, int b, int noisePercentage);

        [DllImport(dllLocation, EntryPoint = "PHAddGaussianNoise", CallingConvention = CallingConvention.Cdecl)]
        public static extern void PHAddGaussianNoise(int addressOriginal, int width, int height, int extraBytes, double sigma, double mu, int noisePercentage);

        [DllImport(dllLocation, EntryPoint = "PHAddPeriodicNoise", CallingConvention = CallingConvention.Cdecl)]
        public static extern void PHAddPeriodicNoise(int addressOriginal, int addressNew, int width, int height, int extraBytes, char amplitude, double fX, double fY, double pX, double pY);
        #endregion

        #region Pixel Operations
        [DllImport(dllLocation, EntryPoint = "PHGammaCorrection", CallingConvention = CallingConvention.Cdecl)]
        public static extern void PHGammaCorrection(int addressOriginal, int addressNew, int width, int height, int extraBytes, float gammaValue);

        [DllImport(dllLocation, EntryPoint = "PHBrightnessCorrection", CallingConvention = CallingConvention.Cdecl)]
        public static extern void PHBrightnessCorrection(int addressOriginal, int addressNew, int width, int height, int extraBytes, float brightnessValue);

        [DllImport(dllLocation, EntryPoint = "PHContrastCorrection", CallingConvention = CallingConvention.Cdecl)]
        public static extern void PHContrastCorrection(int addressOriginal, int addressNew, int width, int height, int extraBytes, float contrastValue);

        [DllImport(dllLocation, EntryPoint = "PHQuantization", CallingConvention = CallingConvention.Cdecl)]
        public static extern void PHQuantization(int addressOriginal, int width, int height, int extraBytes, double value);
        #endregion

        #region Morphology
        [DllImport(dllLocation, EntryPoint = "PHDilation", CallingConvention = CallingConvention.Cdecl)]
        public static extern void PHDilation(int addressOriginal, int addressNew, int width, int height, int extraBytes, byte[,] pMask, int mskHeight, int mskWidth, int centerX, int centerY);

        [DllImport(dllLocation, EntryPoint = "PHDErosion", CallingConvention = CallingConvention.Cdecl)]
        public static extern void PHDErosion(int addressOriginal, int addressNew, int width, int height, int extraBytes, byte[,] pMask, int mskHeight, int mskWidth, int centerX, int centerY);

        [DllImport(dllLocation, EntryPoint = "PHBinaryThreshold", CallingConvention = CallingConvention.Cdecl)]
        public static extern void PHBinaryThreshold(int addressOriginal, int addressNew, int width, int height, int extraBytes, int thresholdValue);

        [DllImport(dllLocation, EntryPoint = "PHMskReflection", CallingConvention = CallingConvention.Cdecl)]
        public static extern void PHMskReflection(byte[,] addressOriginal, byte[,] addressNew, int width, int height);
        #endregion

        [DllImport(dllLocation, EntryPoint = "PHCopyBitmap", CallingConvention = CallingConvention.Cdecl)]
        public static extern void PHCopyBitmap(int addressOriginal, int addressNew, int oldExtraBytes, int newExtraBytes, int width, int height);

        [DllImport(dllLocation, EntryPoint = "PHBitmapFill", CallingConvention = CallingConvention.Cdecl)]
        public static extern void PHBitmapFill(int addressOriginal, int oldExtraBytes, int width, int height, byte red, byte green, byte blue);
    }
}